package core
{
	import flash.display.Loader;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.net.URLRequest;
	import flash.net.URLRequestHeader;
	import flash.net.URLVariables;
	import flash.utils.ByteArray;
	import flash.utils.getTimer;
	
	import org.ais.event.TEvent;
	import org.ais.system.Ais;
	import org.aisy.component.UTimer;
	import org.aisy.display.USprite;
	import org.aisy.net.utils.DataStream;

	public class Loading extends USprite
	{
		public var NAME:String;
		protected var iSwf:USprite;
		/**
		 * 背景
		 */
		protected var bgMc:MovieClip;
		/**
		 * 加载数据
		 */
		protected var iData:*;
		/**
		 * 加载索引
		 */
		protected var index:uint;
		/**
		 * 定时器
		 */
		protected var _utimer:UTimer;
		
		public function Loading(name:String = null)
		{
			NAME = name ? name : "LOADINGVISTA" + getTimer();
			name = null;
		}
		
		public function load(data:*, swf:USprite, movieClip:MovieClip = null):void
		{
			iData = data;
			iSwf = swf;
			iSwf.dynamic = {};
			iSwf.dynamic["NAME"] = NAME;
			iSwf.dynamic["iData"] = iData;
			iSwf.dynamic["assets"] = {};
			
			if (null !== movieClip) bgMc = movieClip;
			else bgMc = new (Ais.IMain.Swf.getClass(Ais.IMain.Swf.hasSwf("url", iSwf.loaderInfo.url) - 1, "LOADING"))();
			addChild(bgMc);
			
			_utimer = new UTimer();
			_utimer.setTimer(__utimerHandler);
			_utimer.setDelay(parseFloat(iData.noticeDelay) ? parseFloat(iData.noticeDelay) : 1000 * 7);
			_utimer.start();
			__utimerHandler();
			
			data = null;
			swf = null;
			
			if (TEvent.trigger("UP_WINDOW_AIS", "SHOW", [this, NAME, 2, false, false, 0, 0, 1, false]) === false) {
				clear();
				return;
			}
			
			__load();
		}
		
		protected function __load():void
		{
			if (index === iData.assets.length) {
				TEvent.trigger(NAME, "LOADING_COMPLETE");
				TEvent.trigger("UP_WINDOW_NEW", "CLEAR", {name: NAME});
				return;
			}
			var asset:Object = iData.assets[index];
			if (asset.type === "binary") __loadBinary(asset);
			else __loadSwf(asset);
			asset = null;
		}
		
		protected function __loadBinary(asset:Object):void
		{
			var dataStream:DataStream = new DataStream();
			dataStream.addEventListener(Event.COMPLETE, __binaryCompleteHandler);
			dataStream.addEventListener(IOErrorEvent.IO_ERROR, __ioErrorHandler);
			dataStream.addEventListener(ProgressEvent.PROGRESS, __progressHandler);
			dataStream.load(getURLRequest(asset));
			dataStream = null;
			asset = null;
		}
		
		protected function __loadSwf(asset:Object):void
		{
			Ais.IMain.Swf.remove(asset.name);
			var swfLoader:* = new (Ais.IMain.getClass("imoon.utils.SwfLoader"))(1);
			swfLoader.addEvent(Event.COMPLETE, __swfCompleteHandler);
			swfLoader.addEvent(IOErrorEvent.IO_ERROR, __ioErrorHandler);
			swfLoader.addEvent(ProgressEvent.PROGRESS, __progressHandler);
			swfLoader.load(getURLRequest(asset));
			swfLoader = null;
			asset = null;
		}
		
		protected function __binaryCompleteHandler(e:Event):void
		{
			var asset:Object = iData.assets[index];
			var dataStream:DataStream = e.currentTarget as DataStream;
			var byteArr:ByteArray = new ByteArray();
			dataStream.readBytes(byteArr, 0, dataStream.bytesAvailable);
			if (!iSwf.dynamic["assets"][asset.name]) {
				iSwf.dynamic["assets"][asset.name] = byteArr;
			}
			else {
				throw Error("there is a same name! index: " + index + " name: " + asset.name);
			}
			index++;
			iSwf.dynamic["index"] = index;
			__load();
			dataStream.clear();
			dataStream = null;
			byteArr = null;
			asset = null;
			e = null;
		}
		
		/**
		 * 
		 * Swf 加载成功侦听
		 * @param e
		 * @param loader
		 * 
		 */
		protected function __swfCompleteHandler(e:Event, loader:Loader):void
		{
			var asset:Object = iData.assets[index];
			Ais.IMain.Swf.put(asset.name, "url", loader.contentLoaderInfo.url);
			Ais.IMain.Swf.put(asset.name, "swf", loader);
			Ais.IMain.LOAD_INT++;
			index++;
			iSwf.dynamic["index"] = index;
			if (parseFloat(asset.timeOut)) {
				var utimer:UTimer = new UTimer();
				utimer.setRepeatCount(1);
				utimer.setDelay(parseFloat(asset.timeOut));
				utimer.setComplete(__load);
				utimer.start();
				utimer = null;
			}
			else __load();
			asset = null;
			loader = null;
			e = null;
		}
		
		/**
		 * 
		 * 加载失败侦听
		 * 此处极有可能是不可原谅的错误
		 * @param e
		 * 
		 */
		protected function __ioErrorHandler(e:IOErrorEvent):void
		{
			TEvent.trigger(NAME, "LOADING_IO_ERROR", e);
			if (bgMc.txt_progress) bgMc.txt_progress.text = iData.assets[index].title + "load failed,please refresh!";
			e = null;
		}
		
		/**
		 * 
		 * 加载进度侦听
		 * @param e
		 * 
		 */
		protected function __progressHandler(e:ProgressEvent):void
		{
			var i:uint = Math.floor((e.bytesLoaded / e.bytesTotal + index) / iData.assets.length * 100);
			if (bgMc.mc_progress) bgMc.mc_progress.gotoAndStop(i);
			if (bgMc.txt_progress) bgMc.txt_progress.text = iData.assets[index].title + " (" + i + "%)" + "..." + (index + 1) + "/" + iData.assets.length;
			var f:Function = function (htmlText:String):void
			{
				if (bgMc.txt_progress) bgMc.txt_progress.htmlText = htmlText;
				htmlText = null;
			};
			TEvent.trigger(NAME, "LOADING_PROGRESS", [e, f]);
			f = null;
			e = null;
		}
		
		protected function getURLRequest(asset:Object):URLRequest
		{
			var request:URLRequest = new URLRequest();
			if (asset.hasOwnProperty("request") === true) {
				var _v:URLVariables = new URLVariables();
				for (var i:String in asset.request) {
					switch (i) {
						case "requestHeaders":
							var requestHeaders:Array = [];
							for each (var j:Array in asset.request.requestHeaders) {
								requestHeaders[requestHeaders.length] = new URLRequestHeader(j[0], j[1]);
							}
							request.requestHeaders = requestHeaders;
							requestHeaders = null;
							break;
						case "data":
							for (var k:String in asset.request.data) {
								_v[k] = asset.request.data[k];
							}
							break;
						case "dataS":
							_v.decode(asset.request.dataS.replace(/^\&/, ""));
							break;
						case "r":
							_v[i] = getTimer() + Math.random();
							break;
						default:
							request[i] = asset.request[i];
							break;
					}
				}
				request.data = _v;
				_v = null;
			}
			request.url = asset.url;
			asset = null;
			return request;
		}
		
		/**
		 * 
		 * UTimer 侦听
		 * 
		 */
		protected function __utimerHandler():void
		{
			if (iData.notice) {
				var i:int = Math.round(Math.random() * (iData.notice.length - 1));
				if (bgMc.txt_notice) bgMc.txt_notice.text = iData.notice[i];
				if (bgMc.mc_notice) bgMc.mc_notice.gotoAndStop(i + 1);
			}
		}
		
		override public function get width():Number
		{
			var _w:Number = parseFloat(iSwf.loaderInfo.parameters["width"]);
			if (/\%$/.test(iSwf.loaderInfo.parameters["width"])) {
				_w *= Ais.IMain.stage.stageWidth * 0.01;
			}
			return _w ? _w : super.width;
		}
		
		override public function get height():Number
		{
			var _h:Number = parseFloat(iSwf.loaderInfo.parameters["height"]);
			if (/\%$/.test(iSwf.loaderInfo.parameters["height"])) {
				_h *= Ais.IMain.stage.stageHeight * 0.01;
			}
			return _h ? _h : super.height;
		}
		
		/**
		 * 
		 * 清空
		 * 
		 */
		override public function clear():void
		{
			TEvent.clearTrigger(NAME);
			if (null !== _utimer) _utimer.clear();
			_utimer = null;
			bgMc = null;
			iData = null;
			NAME = null;
			super.clear();
			if (Boolean(parseInt(iSwf.loaderInfo.parameters["clear"])) === true) {
				var imoonIndex:int = Ais.IMain.Swf.hasSwf("url", iSwf.loaderInfo.url);
				Ais.IMain.Swf.remove(imoonIndex - 1);
				Ais.IMain.Swf.remove(imoonIndex - 1);
			}
			iSwf = null;
		}
		
	}
}